/*
 * Title:        CloudScheduler Toolkit
 * Description:  a Toolkit for Modeling and Simulation of Job Scheduling and Resource Provisioning in Cloud System
 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
 * Author:       Fuhui Wu
 *
 * Copyright (c) 2013-2014, The National University of Defense Technology, China
 */

package org.nudt.jCloud.example.evaluation;

import org.nudt.jCloud.evaluation.Evaluation;
import org.nudt.jCloud.infrastructure.HomegeneousCluster;
import org.nudt.jCloud.infrastructure.SlotType;
import org.nudt.jCloud.jobScheduler.AFCFSScheduler;
import org.nudt.jCloud.jobScheduler.JobScheduler;
import org.nudt.jCloud.resourceManager.GeneralShareStateRM;
import org.nudt.jCloud.resourceManager.ResManager;
import org.nudt.jCloud.resourceScaler.ResourceScaler;
import org.nudt.jCloud.resourceScaler.ThresholdScaler;
import org.nudt.jCloud.simulation.CloudSchedSIM;
import org.nudt.jCloud.simulation.SIMTag;
import org.nudt.jCloud.simulation.User;
import org.nudt.jCloud.simulation.UserBroker;
import org.nudt.jCloud.workload.BatchWLGen;
import org.nudt.jCloud.workload.Workload;
import org.nudt.jCloud.workload.WorkloadGenerator;

public class ConcurrentOverhead_Example {
	
	private static HomegeneousCluster homeCluster;
	private static ResManager shareStateRM;
	private static UserBroker userBroker1;
	private static JobScheduler jobScheduler1;
	private static ResourceScaler resourceScaler1;
	private static User user1;
	private static UserBroker userBroker2;
	private static JobScheduler jobScheduler2;
	private static ResourceScaler resourceScaler2;
	private static User user2;
	private static Workload wl1;
	private static Workload wl2;
	
	public static void init(double thinkTimeOfJob, double thinkTimeOfTask){
		SlotType slotType = new SlotType(1, 1000, 250, 0);
		WorkloadGenerator wlGen1 = new BatchWLGen(500, 100, 50, 0.5, 60, slotType);
		wl1 = wlGen1.generate(0);
		wl1.setThinkTimeOfJob(thinkTimeOfJob);
		wl1.setThinkTimeOfTask(thinkTimeOfTask);
		WorkloadGenerator wlGen2 = new BatchWLGen(500, 100, 50, 0.5, 60, slotType);
		wl2 = wlGen2.generate(0);
		wl2.setThinkTimeOfJob(thinkTimeOfJob);
		wl2.setThinkTimeOfTask(thinkTimeOfTask);
		
		homeCluster = new HomegeneousCluster(20, 1000, 4, 4000, 1000, 200000);
		shareStateRM = new GeneralShareStateRM("ShareStateRM", homeCluster);		
		userBroker1 = new UserBroker("UserBroker1", SIMTag.RM_MODE_S);
		resourceScaler1 = new ThresholdScaler(2, 0.5);
		jobScheduler1 = new AFCFSScheduler("FCFS");
		user1 = new User("user1", wl1);
		userBroker2 = new UserBroker("UserBroker2", SIMTag.RM_MODE_S);
		resourceScaler2 = new ThresholdScaler(2, 0.5);
		jobScheduler2 = new AFCFSScheduler("FCFS");
		user2 = new User("user2", wl2);

	}
	

	public static void main(String[] args){
		init(0.01, 0.005);
		CloudSchedSIM.init("ConcurrentOverheadExample_1");
		userBroker1.init(jobScheduler1, resourceScaler1);
		userBroker1.addUser(user1);
		userBroker2.init(jobScheduler2, resourceScaler2);
		userBroker2.addUser(user2);
		CloudSchedSIM.addRM(shareStateRM);
		CloudSchedSIM.addUserBroker(userBroker1);
		CloudSchedSIM.addUserBroker(userBroker2);
		CloudSchedSIM.startSimulation();
		
		//restart("ConcurrentOverheadExample_2", 20, 50, 20, 50);
		//restart("ConcurrentOverheadExample_3", 0.5, 0.25);
		
		Evaluation.wlSize(wl1);
		Evaluation.wlSize(wl2);
		printResult("ConcurrentOverheadExample_1");
		//printResult("ConcurrentOverheadExample_2");
		//printResult("ConcurrentOverheadExample_3");
	}
	
	public static void printResult(String simName){
		System.out.println();
		Evaluation.jobSchedulerBusyTime(simName, "userBroker1");
		Evaluation.jobSchedulerBusyTime(simName, "userBroker2");
		System.out.println();
		Evaluation.concurrentFailureCount(simName, "userBroker1");
		Evaluation.concurrentFailureCount(simName, "userBroker2");
		System.out.println();
		Evaluation.avgWaitTime(simName, "user1");
		Evaluation.avgWaitTime(simName, "user2");
	}
	
	public static void restart(String simName,
			double avgJobInterarrivalTime1, double avgTaskDuration1,
			double avgJobInterarrivalTime2, double avgTaskDuration2){
		SlotType slotType = new SlotType(1, 1000, 250, 0);
		WorkloadGenerator wlGen1 = new BatchWLGen(1000, avgJobInterarrivalTime1,
				avgTaskDuration1, 0.5, 80, slotType);
		Workload wl1 = wlGen1.generate(0);
		wl1.setThinkTimeOfJob(1);
		wl1.setThinkTimeOfTask(0.5);
		WorkloadGenerator wlGen2 = new BatchWLGen(1000, avgJobInterarrivalTime2,
				avgTaskDuration2, 0.5, 80, slotType);
		Workload wl2 = wlGen2.generate(0);
		wl2.setThinkTimeOfJob(1);
		wl2.setThinkTimeOfTask(0.5);
		CloudSchedSIM.reset(simName);
		shareStateRM.reset();
		userBroker1.reset();
		userBroker1.setRM_Mode(SIMTag.RM_MODE_S);
		jobScheduler1.reset();
		resourceScaler1.reset();
		userBroker1.init(jobScheduler1, resourceScaler1);
		user1.reset();
		user1.setWl(wl1);
		userBroker1.addUser(user1);		
		userBroker2.reset();
		userBroker2.setRM_Mode(SIMTag.RM_MODE_S);
		jobScheduler2.reset();
		resourceScaler2.reset();
		userBroker2.init(jobScheduler2, resourceScaler2);
		user2.reset();
		user2.setWl(wl2);
		userBroker2.addUser(user2);
		CloudSchedSIM.addRM(shareStateRM);
		CloudSchedSIM.addUserBroker(userBroker1);
		CloudSchedSIM.addUserBroker(userBroker2);
		CloudSchedSIM.startSimulation();
	}
	
}
